#include "NxModelServiceInstance.h"
#include "NxModelServiceInstanceFactory.h"
#include "NxRunningLogFactory.h"
#include "../utils/NxHttp.h"
#include "../utils/NxCommon.h"
#include "json/json.h"
#include <time.h>

const char* NJGIS::SERVICE::NjModelServiceInstance::getCurrentState()
{
	return this->_state.c_str();
}

const char* NJGIS::SERVICE::NjModelServiceInstance::getCurrentEvent()
{
	return this->_event.c_str();
}

const char* NJGIS::SERVICE::NjModelServiceInstance::getGUID()
{
	return this->_guid.c_str();
}

const char* NJGIS::SERVICE::NjModelServiceInstance::getStartTime()
{
	return this->_guid.c_str();
}

const char* NJGIS::SERVICE::NjModelServiceInstance::getModelServiceID()
{
	return this->_serviceID.c_str();
}

std::vector<NJGIS::SERVICE::INjRunningLog*>* NJGIS::SERVICE::NjModelServiceInstance::getLogs()
{
	return this->_logs;
}

std::vector<NJGIS::SERVICE::INjRunningLog*>* NJGIS::SERVICE::NjModelServiceInstance::getNewLogs()
{
	std::vector<NJGIS::SERVICE::INjRunningLog*>* nlog = new std::vector<NJGIS::SERVICE::INjRunningLog*>();
	for(int i = 0; i < (this->_logs)->size(); i++)
	{
		if(!(*this->_logs)[i]->getMark())
		{
			(*this->_logs)[i]->setMark(true);
			nlog->push_back((*this->_logs)[i]);
		}
	}
	return nlog;
}

NJGIS::SERVICE::NjModelInstanceStatus NJGIS::SERVICE::NjModelServiceInstance::getStatus()
{
	return this->_status;
}

int NJGIS::SERVICE::NjModelServiceInstance::kill()
{
	Json::Value jsResponse;
	std::string url;
	this->getBaseUrl(url);
	url += "modelins/"; 
	url += this->getGUID();
	url += "?ac=kill";
	NJGIS::SERVICE::NjHttpHelper::request_put_json_sync(url.c_str(), jsResponse);
	if(jsResponse["result"].asString() == "suc")
	{
		return 1;
	}
	else if(jsResponse["result"].asString() == "fail")
	{
		return -2;
	}
	return -1;
}

int NJGIS::SERVICE::NjModelServiceInstance::pause()
{
	Json::Value jsResponse;
	std::string url;
	this->getBaseUrl(url);
	url += "modelins/"; 
	url += this->getGUID();
	url += "?ac=pause";
	NJGIS::SERVICE::NjHttpHelper::request_put_json_sync(url.c_str(), jsResponse);
	if(jsResponse["result"].asString() == "suc")
	{
		return 1;
	}
	else if(jsResponse["result"].asString() == "fail")
	{
		return -2;
	}
	return -1;
}

int NJGIS::SERVICE::NjModelServiceInstance::restart()
{
	Json::Value jsResponse;
	std::string url;
	this->getBaseUrl(url);
	url += "modelins/"; 
	url += this->getGUID();
	url += "?ac=restart";
	NJGIS::SERVICE::NjHttpHelper::request_put_json_sync(url.c_str(), jsResponse);
	if(jsResponse["result"].asString() == "suc")
	{
		return 1;
	}
	else if(jsResponse["result"].asString() == "fail")
	{
		return -2;
	}
	return -1;
}

int NJGIS::SERVICE::NjModelServiceInstance::refresh()
{
	Json::Value jsResponse;
	std::string url;
	this->getBaseUrl(url);
	url += "modelins/json/"; 
	url += this->getGUID();
	NJGIS::SERVICE::NjHttpHelper::request_get_json_sync(url.c_str(), jsResponse);
	if(jsResponse["result"].asString() == "suc")
	{
		Json::Value mis = jsResponse["data"];
		if(mis == Json::nullValue)
		{
			this->_status = NJGIS::SERVICE::NjModelInstanceStatus::INSTA_FINISHED;
			return 1;
		}
		else
		{
			this->_event = mis["event"].asString();
			this->_state = mis["state"].asString();
			this->_status = NJGIS::SERVICE::NjModelServiceInstanceFactory::convertString2Status(mis["status"].asCString());
			NJGIS::SERVICE::NJRunningLogFactory::convertJson2Logs(mis["log"], this->_logs);
			this->_statusDes = mis["statusDes"].asCString();
		}
		return 1;
	}
	else if(jsResponse["result"].asString() == "err")
	{
		return -2;
	}
	return -1;
}

int NJGIS::SERVICE::NjModelServiceInstance::wait4Status( NJGIS::SERVICE::NjModelInstanceStatus status, double timeout /*= 7200*/, bool log )
{
	time_t time_now;
	time(&time_now);
	time_t time_end = time_now + timeout;
	while(this->_status != status && time_now < time_end)
	{
		time(&time_now);
		NJGIS::SERVICE::NjCommonLibrary::sleep(2);
		this->refresh();
		if(log)
		{
			std::vector<INjRunningLog*>* list_logs = this->getNewLogs();
			int count = list_logs->size();
			for(int i = 0; i < count; i++)
			{
				(*list_logs)[i]->print();
			}
		}
	}
	if(this->_status == status)
	{
		return 1;
	}
	return -1;
}